/*
 * @Author: master
 * @Date: 2022-04-02 09:52:32
 * @LastEditTime: 2022-04-07 17:49:15
 * @Description: vite mock服务钩子
 */
import Mock from 'mockjs'; // 模拟数据
import chokidar from 'chokidar'; // 监听系统文件变化
import { isFile } from '../node/util.js'; // node工具
const fs = require('fs'); // 文件服务
const path = require('path'); // 路径服务
/**
 * mock接收模拟数据
 * @param {*} result
 * @returns
 */
const mockRequest = result => {
  const data = Mock.mock({
    ...result,
  });
  // eslint-disable-next-line no-prototype-builtins
  return data ? (data.hasOwnProperty('mock') ? data.mock : '') : '';
};
/**
 * /**
 * 获取mock的json文件
 * @param {*} mockPath mock文件夹路径
 * @returns Array JSON
 */
const getProMockConfig = mockPath => {
  const file = fs.statSync(mockPath);
  // 数据集合
  const mockJsons = [];
  if (file.isDirectory()) {
    /**
     * 解析mock的json文件
     */
    const files = fs.readdirSync(mockPath);
    files.forEach(fileName => {
      // 获取文件扩展名，只对.json文件解析
      const extname = path.extname(fileName);
      if (extname === '.json') {
        const fillPath = mockPath + '/' + fileName;
        const data = fs.readFileSync(fillPath, 'utf8');
        if (data) {
          const result = JSON.parse(data); // 读取的值
          if (typeof result === 'object' && result instanceof Array) {
            mockJsons.push(result);
          }
        }
      }
    });
  }
  return mockJsons;
};
/**
 * mock服务，服务类型访问，包含：get、post、put、delete，
 * @param {Object} viteConfig
 */
const viteMockPlugin = viteConfig => {
  const projectMockPath = path.join(`${viteConfig.root}`, '/mock');
  const state = isFile(projectMockPath);
  if (!state) {
    return null;
  }
  // mock的数据集合
  const mockData = {};
  /**
   * 创建mock服务
   */
  const createMockServer = async () => {
    /**
     * set mock data
     */
    const setMockData = res => {
      if (res && res instanceof Array && res.length > 0) {
        res.forEach(json => {
          if (json && json instanceof Array && json.length > 0) {
            json.forEach(item => {
              if (item.method && item.url && item.result) {
                mockData[item.url] = item;
              }
            });
          }
        });
      }
    };
    /**
     * create watch mock
     */
    const createWatch = () => {
      if (process.env.VITE_DISABLED_WATCH_MOCK === 'true') {
        return;
      }
      const watchDir = [];
      const exitsConfigPath = fs.existsSync(projectMockPath);
      if (exitsConfigPath) {
        watchDir.push(projectMockPath);
        const watcher = chokidar.watch(watchDir, {
          ignoreInitial: true,
        });
        watcher.on('all', async (event, file) => {
          // 获取mock的json文件
          const response = getProMockConfig(projectMockPath);
          // set mock data
          setMockData(response);
        });
      }
    };
    // 获取mock的json文件
    const response = getProMockConfig(projectMockPath);
    // set mock data
    setMockData(response);
    // create watch mock
    await createWatch();
  };
  return {
    name: 'vite-mock-server',
    enforce: 'pre',
    // 钩子读取和存储的配置
    configResolved() {
      // 创建mock服务
      createMockServer();
    },
    // 开发服务器的钩子
    configureServer({ middlewares }) {
      middlewares.use((req, res, next) => {
        if (mockData[req.url]) {
          res.setHeader('Content-Type', 'application/json');
          res.statusCode = 200;
          // mock接收模拟数据
          const data = mockRequest(mockData[req.url].result);
          res.end(
            JSON.stringify({
              code: '200',
              data,
              message: 'success',
            }),
          );
        } else {
          next();
        }
      });
    },
  };
};
export default viteMockPlugin;
